
# 导入班级科目分配模型
import django
from core.models.class_subject_assignment import ClassSubjectAssignment
from core.models.school_schedule import SchoolSchedule
from django.shortcuts import render
from core.models.student import Student
from core.models.classinfo import ClassInfo
from core.models.daily_attendance import DailyAttendance
from datetime import date, datetime, timedelta
from core.models.leave_request import LeaveRequest
from core.models.discipline import DisciplineRecord
from core.models.homework_submission import HomeworkSubmission
from core.models.homework import Homework
from django.db.models import Count, Case, When
from core.models.log import OperationLog
from django.utils import timezone


# 获取用户对应的班级信息
def get_class(user):
    """
    根据用户信息获取其担任班主任的班级信息。

    :param user: 用户对象
    :return: 班级信息对象，如果不存在则返回 None
    """
    classinfo = ClassInfo.objects.filter(homeroom_teacher=user).first()
    return classinfo




#获取用户的角色
def get_user_role(user):
    """
    根据用户信息获取其角色名称。

    :param user: 用户对象
    :return: 角色名称字符串
    """
    # 通过UserRoleAssignment获取角色
    role_assignment = user.role_assignments.select_related('role').first()
    role_name = role_assignment.role.name if role_assignment else 'unknown'
    return role_name

# 获取用户对应的所有班级信息
def get_classes(user):
    """
    根据用户角色获取其可管理的班级信息。

    :param user: 用户对象
    :return: 班级信息查询集
    """
    role = get_user_role(user)
    if role == 'grade_leader':
        # 年级主任可以查看其年级下的所有班级
        return ClassInfo.objects.filter(grade__grade_leader=user)
    elif role == 'admin':
        # 管理员可以查看所有班级
        return ClassInfo.objects.all()
    else:
        # 其他角色（如班主任）只能查看自己担任班主任的班级
        return ClassInfo.objects.filter(homeroom_teacher=user)

# 获取用户通过科目分配的班级
def get_user_subject_classes(user):
    """
    获取用户通过科目分配的所有班级。

    :param user: 用户对象
    :return: 班级信息查询集
    """
    from core.models.teacher_subject_assignment import TeacherSubjectAssignment
    return ClassInfo.objects.filter(
        id__in=ClassSubjectAssignment.objects.filter(
            subject_id__in=TeacherSubjectAssignment.objects.filter(
                teacher=user
            ).values_list('subject_id', flat=True)
        ).values_list('class_id', flat=True)
    ).distinct()

# 获取指定班级的科目列表函数
def get_subject(classinfo):
    """
    根据班级信息获取该班级的所有科目名称列表。

    :param classinfo: 班级信息对象
    :return: 科目名称列表
    """
    subject = ClassSubjectAssignment.objects.filter(class_id=classinfo)
    subject_list = []
    for item in subject:
        subject_list.append(item.subject.name)
    return subject_list


    
def get_target_date(prev):
    """
    根据传入的天数偏移量计算目标日期。

    :param prev: 天数偏移量，整数类型。正数表示未来日期，负数表示过去日期。
    :return: 目标日期的字符串，格式为 'YYYY-MM-DD'。
    """
    prev=int(prev)
    # 导入 datetime 和 timedelta 用于日期计算
    from datetime import datetime, timedelta
    # 获取当前日期
    current_date = datetime.now().date()
    # 根据偏移量计算目标日期
    target_date = current_date + timedelta(days=prev)
    # 将目标日期转换为 'YYYY-MM-DD' 格式的字符串
    target_date_str = target_date.strftime('%Y-%m-%d')
    return target_date_str



def get_daily_attendance_and_task_stats(class_id, date):
    """
    合并统计指定班级和日期的学生出勤及清洁任务完成情况
    :param class_id: 班级ID
    :param date: 统计日期（datetime对象）
    :return: 字典，包含：
        'late_stats': {'morning': 迟到人数, 'afternoon': 迟到人数, 'evening': 迟到人数},
        'task_completion': (完成任务数量, 总任务数量)
    """
    classes=ClassInfo.objects.filter(id=class_id).first()
    attendance_records = DailyAttendance.objects.filter(student__classes__id=class_id, date=date)
    # 统计出勤情况
    late_stats = {
        'morning': sum(1 for r in attendance_records if r.morning_attendance),
        'afternoon': sum(1 for r in attendance_records if r.afternoon_attendance),
        'evening': sum(1 for r in attendance_records if r.evening_attendance),
        'cleaning_task':sum(1 for r in attendance_records if r.cleaning_task_completed)
    }
    return {
        'late_stats': late_stats
    }


def get_leave_and_discipline_counts(class_id, date):
    """
    统计指定班级和日期的请假次数及违纪次数
    :param class_id: 班级ID
    :param date: 统计日期（date对象）
    :return: 字典，包含'leave_count'（请假次数）和'discipline_count'（违纪次数）
    """
    # 统计请假次数（请假日期包含目标日期）
    leave_count = LeaveRequest.objects.filter(
        student__classes__id=class_id,
        start_date__lte=date,
        end_date__gte=date
    ).count()

    # 统计违纪次数（违纪时间在目标日期）
    discipline_count = DisciplineRecord.objects.filter(
        student__classes__id=class_id,
        happened_at__date=date
    ).count()
    return {
        'leave_count': leave_count,
        'discipline_count': discipline_count
    }


def get_student_performance_stats(class_id, date):
    """
    计算指定班级在特定日期的学生表现统计数据
    
    参数:
        class_id: 班级ID
        date: 统计日期 (datetime.date对象)
    
    返回:
        list: 包含每个学生表现数据的字典列表
    """
    # 统计指定班级的学生信息（包含ID和姓名）
    students = Student.objects.filter(classes__id=class_id).values('id', 'name')
    performance_data = {}
    
    # 获取班级所有学科
    subjects = ClassSubjectAssignment.objects.filter(class_id=class_id)
    subject_ids = [assignment.subject_id for assignment in subjects]
    
    for student in students:
        student_id = student['id']
        student_name = student['name']
        
        # 迟到次数（早中晚累计）
        late_stats = DailyAttendance.objects.filter(
            student_id=student_id, date=date
        ).aggregate(
            morning=Count(Case(When(morning_attendance=True, then=1))),
            afternoon=Count(Case(When(afternoon_attendance=True, then=1))),
            evening=Count(Case(When(evening_attendance=True, then=1)))
        )
        total_late = sum(late_stats.values())
        
        # 作业未交次数（各科累计）
        no_homework_count = HomeworkSubmission.objects.filter(
            student_id=student_id,
            status='missing',
            homework__class_subject__subject_id__in=subject_ids,
            homework__due_date__lte=date
        ).count()
        
        # 请假次数（已批准且包含统计日期）
        leave_count = LeaveRequest.objects.filter(
            student_id=student_id,
            start_date__lte=date,
            end_date__gte=date,
            status='approved'
        ).count()
        
        # 违纪次数（违纪时间在统计日期）
        discipline_count = DisciplineRecord.objects.filter(
            student_id=student_id,
            happened_at__date=date
        ).count()
        
        # 表彰次数（表彰日期在统计日期）
        from core.models.honor import HonorRecord
        honor_count = HonorRecord.objects.filter(
            student_id=student_id,
            award_date=date
        ).count()
        
        # 整合学生表现数据
        performance_data[student_id] = {
            'student_id': student_id,
            'student_name': student_name,
            'late_count': total_late,
            'unsubmitted_homework_count': no_homework_count,
            'leave_count': leave_count,
            'discipline_count': discipline_count,
            'honor_count': honor_count
        }
    
    return list(performance_data.values())


def get_class_subjects(class_id,datestr):
    """
    获取指定班级分配的学科列表
    :param class_id: 班级ID
    :return: 学科名称列表（如 ['数学', '语文']）
    """
    # 查询该班级的所有学科分配记录
    assignments = ClassSubjectAssignment.objects.filter(class_id=class_id)
    # 提取学科名称
    subjects = [assignment.subject.name for assignment in assignments]
    no_homework_list=[]

    #取得各学科未交作业的人数
    for subject in subjects:
        #根据学科和截至时间得到所有的老师布置的作业
        homeworks=Homework.objects.filter(class_subject__subject__name=subject,
        due_date=datestr)
        #根据Homework的id得到所有的学生提交的作业
        no_homework_count=HomeworkSubmission.objects.filter(
            homework__in=homeworks,
            status='missing'
        ).count()
        no_homework_list.append(no_homework_count)
    
    return {'subject_name_list':subjects,'no_homework_count':no_homework_list}




'''
    获取本周的日期列表
    '''
def get_week_dates(today):
    # 计算今天是星期几（0=周一，6=周日）
    
    date=datetime.strptime(today,'%Y-%m-%d')
    weekday = date.weekday()
    # 计算周一的日期（减去当前星期几的天数）
    monday = date - timedelta(days=weekday)
    # 生成本周所有日期（周一到周日）
    week_dates = [monday + timedelta(days=i) for i in range(7)]
    return week_dates

   
    '''
    获取本月的日期列表
    '''
def get_month_dates(today):
    # 获取本月第一天
    first_day = today.replace(day=1)
    # 计算下个月的第一天，然后减去一天得到本月最后一天
    next_month = first_day.replace(month=first_day.month + 1) if first_day.month < 12 else first_day.replace(year=first_day.year + 1, month=1)
    last_day = next_month - timedelta(days=1)
    # 生成本月所有日期
    days_in_month = []
    current_day = first_day
    
    while current_day <= last_day:
        days_in_month.append(current_day)
        current_day += timedelta(days=1)
    return days_in_month
    '''
    获取本年的日期列表
    '''
def get_year_dates(today):
    # 获取本年第一天
    first_day = today.replace(month=1, day=1)
    
    # 获取下一年第一天，再减去一天得到本年最后一天
    next_year = first_day.replace(year=first_day.year + 1)
    last_day = next_year - timedelta(days=1)
    
    # 生成本年所有日期
    days_in_year = []
    current_day = first_day
    
    while current_day <= last_day:
        days_in_year.append(current_day)
        current_day += timedelta(days=1)
    
    return days_in_year
    '''
    获取迟到次数
    '''
def get_count(list):
    count=0
    for item in list:
        if item.morning_attendance==True:
            count+=1
        if item.afternoon_attendance==True:
            count+=1
        if item.evening_attendance==True:
            count+=1
    return count


    '''
    获取没有交作业的次数
    '''
def get_no_homework_count(stu,type='today'):
    """
    获取学生的作业未交次数。

    :param student_id: 学生ID
    :return: 作业未交次数
    """
    count=0
    return count
   
'''
是否发出预警
'''
def get_warning(stu,type='today'):
    """
    获取学生的预警情况。
    :param student_id: 学生ID
    :return: 预警情况
    """
    return False



